# 真实版FaceRecognition类，使用face_recognition库实现真实的人脸识别功能
import face_recognition
import numpy as np
from PIL import Image
import io

class FaceRecognition:
    def __init__(self):
        print("使用真实版FaceRecognition类")
    
    def extract_face_encoding(self, image_data):
        """
        从二进制图像数据中提取人脸编码
        
        参数:
            image_data: 二进制图像数据
            
        返回:
            numpy数组: 人脸编码，如果未检测到人脸则返回None
        """
        try:
            # 使用face_recognition库直接处理二进制数据
            image = face_recognition.load_image_file(io.BytesIO(image_data))
            
            # 获取人脸编码
            face_encodings = face_recognition.face_encodings(image)
            
            # 如果检测到人脸，返回第一个人脸的编码
            if len(face_encodings) > 0:
                # 转换为列表格式返回，避免NumPy数组在传输中的问题
                return face_encodings[0].tolist()
            else:
                print("未检测到人脸")
                return None
                
        except Exception as e:
            print(f"提取人脸编码时出错: {str(e)}")
            return None
    
    def compare_faces(self, face_encoding, known_face_encodings):
        """比对人脸编码与已知人脸编码
        
        参数:
            face_encoding: 待比对的人脸编码
            known_face_encodings: 已知人脸编码列表
            
        返回:
            tuple: (是否匹配, 匹配的索引，如果没有匹配则为-1)
        """
        try:
            print(f"比较人脸 - 待比对编码类型: {type(face_encoding)}")
            print(f"已知编码数量: {len(known_face_encodings)}，第一个编码类型: {type(known_face_encodings[0]) if known_face_encodings else '无'}")
            
            # 转换为numpy数组以提高计算精度和速度
            if isinstance(face_encoding, list):
                face_encoding_np = np.array(face_encoding)
            else:
                face_encoding_np = face_encoding
            
            # 转换已知编码为numpy数组列表
            known_encodings_np = []
            for encoding in known_face_encodings:
                if isinstance(encoding, list):
                    known_encodings_np.append(np.array(encoding))
                else:
                    known_encodings_np.append(encoding)
            
            # 使用face_recognition库内置的函数进行比较，使用更严格的容差
            # 降低容差值以提高准确率，0.5-0.55是比较严格的值
            tolerance = 0.53
            
            # 计算所有人脸编码的距离
            face_distances = face_recognition.face_distance(known_encodings_np, face_encoding_np)
            
            # 找出最小距离和对应的索引
            min_distance = min(face_distances)
            best_match_index = np.argmin(face_distances)
            
            # 详细的日志记录
            print(f"所有距离值: {face_distances}")
            print(f"最小距离: {min_distance}, 最佳匹配索引: {best_match_index}")
            
            # 只有当最小距离远低于容差时才认为匹配
            # 添加额外的条件：确保最小距离明显小于容差，而不是接近容差
            if min_distance < tolerance and min_distance < tolerance * 0.95:
                print(f"确认匹配 - 距离{min_distance}远低于容差{tolerance}")
                return (True, best_match_index)
            else:
                print(f"不匹配 - 距离{min_distance}高于或接近容差{tolerance}")
                return (False, -1)
                
        except Exception as e:
            print(f"比较人脸时出错: {str(e)}")
            # 出错时返回不匹配，避免误识别
            return (False, -1)
    
    def detect_faces(self, image_data):
        """检测图像中的人脸位置
        
        参数:
            image_data: 图像的二进制数据
            
        返回:
            list: 人脸位置列表，每个位置为(top, right, bottom, left)格式
        """
        try:
            # 直接使用face_recognition库加载图像
            image = face_recognition.load_image_file(io.BytesIO(image_data))
            
            # 检测人脸位置
            face_locations = face_recognition.face_locations(image)
            
            return face_locations
            
        except Exception as e:
            print(f"检测人脸位置时出错: {str(e)}")
            return []